package com.sinog.front.service.azbj.uploadappendix;

import com.alibaba.fastjson.JSONArray;
import com.sinog.core.util.JsonUtil;
import com.sinog.core.utilbean.Constants;
import com.sinog.front.controller.biz.AbryXjController;
import com.sinog.front.controller.biz.PrisonerTransferController;
import com.sinog.front.controller.biz.ReleaseHelpEduController;
import com.sinog.front.controller.biz.SlgInfoController;
import com.sinog.front.controller.work.WorkController;
import com.sinog.front.feign.biz.SearchCodeList;
import com.sinog.front.util.FileUtil;
import com.sinog.front.util.PoiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @desc 文件上传处理类
 * @author hak
 * date -
 */
@Slf4j
@Service
public class UploadExcelService {

    @Autowired
    private SearchCodeList searchCodeList;
    @Autowired
    private WorkController workController;
    @Autowired
    private AbryXjController abryXjController;
    @Autowired
    private SlgInfoController slgInfoController;
    @Autowired
    private PrisonerTransferController prisonerTransferController;
    @Autowired
    private ReleaseHelpEduController releaseHelpEduController;

    /**
     * 安帮工作资源管理 - 安帮工作人员信息管理 - 导出列表数据
     * @param request request
     * @param map map
     * @param excelName excelName
     * @param templateUrl templateUrl
     * @param response response
     */
    public void exportExcelFile(HttpServletRequest request,Map<String,Object> map,String excelName,String templateUrl,HttpServletResponse response) throws IOException {
        FileUtil.exportExcelFile(request,map,excelName,templateUrl,response);
    }

    /**
     * 搜索条件，取最近的一次的key，获取搜索条件
     * @param map 存放redis封装的搜索信息
     * @return 搜索条件
     */
    private Map<String,String> getSearchMap(Map<String,Object> map) {
        Map<Long,Object> searchMap = (Map<Long,Object>)map.get("searchMap");
        Long searchKey = searchMap.keySet().stream().mapToLong(Long::valueOf).max().getAsLong();
        return (Map<String,String>)searchMap.get(searchKey);
    }

    /**
     * 描述
     * @param map map
     * @return Map<String,Object>
     */
    private Map<String,Object> getSearchMapObject(Map<String,Object> map) {
        Map<Long,Object> searchMap = (Map<Long,Object>)map.get("searchMap");
        Long searchKey = searchMap.keySet().stream().mapToLong(Long::valueOf).max().getAsLong();
        return (Map<String,Object>)searchMap.get(searchKey);
    }

    /**
     * 封装查询得到的数据
     * @param map map封装的数据
     * @param searchMap searchMap
     * @param type type
     * @return List<Map < String,String>>
     */
    private List<Map<String,String>> getData(Map<String,Object> map,Map<String,String> searchMap,String type) {
        List<Map<String,String>> mapList = (List<Map<String,String>>)map.get("dataList");
        //核查
        String state = searchMap.get("state");
        //衔接
        String stateXj = searchMap.get("stateXj");
        //双列列管
        String keyState = searchMap.get("key");
        //迁移
        String typeState = searchMap.get("type");
        //解除帮教
        String shKeyState = searchMap.get("shKey");
        //同一个角色下不同状态下的导出（没有勾选批量导出）
        if(Constants.NumberStr.NUM_STR_NINE.equals(type)) {
            Map<String,Object> stringObjectMap;
            searchMap.remove("departid");
            searchMap.remove("level");
            searchMap.remove("account");
            //初始化分页。
            searchMap.put("pageIndex",Constants.NumberStr.NUM_STR_ZERO);
            //该状态下总数量
            String total = searchMap.get("total");
            searchMap.put("pageSize",total);
            if(state != null) {
                //核查
                String arrayMaps = workController.getWorkVerificationList(searchMap,null,null);
                stringObjectMap = JsonUtil.toMap(arrayMaps);
                mapList = JSONArray.parseObject(stringObjectMap.get("data").toString(),List.class);
            } else if(stateXj != null) {
                //衔接
                Map<String,Object> searchMapObject = this.getSearchMapObject(map);
                searchMapObject.put("pageIndex",searchMap.get("pageIndex"));
                searchMapObject.put("pageSize",searchMap.get("pageSize"));
                searchMapObject.remove("departid");
                searchMapObject.remove("level");
                searchMapObject.remove("account");
                String arrayMaps = abryXjController.toXxblPublicList(searchMapObject);
                stringObjectMap = JsonUtil.toMap(arrayMaps);
                mapList = JSONArray.parseObject(stringObjectMap.get("data").toString(),List.class);
            } else if(keyState != null) {
                //双列管
                String slgJzd = slgInfoController.getSlgJzd(Integer.valueOf(searchMap.get("pageIndex")),Integer.valueOf(searchMap.get("pageSize")),searchMap.get("pName"),searchMap.get("key"),searchMap.get("sqbegin"),searchMap.get("sqend"),searchMap.get("nativepro"),searchMap.get("nativecity"),searchMap.get("nativecou"),searchMap.get("nativevill"),searchMap.get("isDoubleManage"),searchMap.get("nameKey"),searchMap.get("zdbjKey"),searchMap.get("shenKey"),searchMap.get("zmKey"),searchMap.get("fxKey"),searchMap.get("qitaKey"),searchMap.get("rjStartDate"),searchMap.get("rjEndDate"),null,null);
                stringObjectMap = JsonUtil.toMap(slgJzd);
                mapList = JSONArray.parseObject(stringObjectMap.get("data").toString(),List.class);
            } else if(typeState != null) {
                //迁移
                Map<String,Object> parameterMap = this.getSearchMapObject(map);
                parameterMap.remove("departid");
                parameterMap.remove("level");
                parameterMap.remove("account");
                String fqTranslateBaseInfoList = prisonerTransferController.getFqTranslateBaseInfoList(Integer.valueOf(searchMap.get("pageIndex")),Integer.valueOf(searchMap.get("pageSize")),null,null,parameterMap);
                stringObjectMap = JsonUtil.toMap(fqTranslateBaseInfoList);
                mapList = JSONArray.parseObject(stringObjectMap.get("data").toString(),List.class);
            } else if(shKeyState != null) {
                //帮教
                Map<String,Object> parameterMap = this.getSearchMapObject(map);
                parameterMap.remove("departid");
                parameterMap.remove("level");
                parameterMap.remove("account");
                String releaseHelpEduList = releaseHelpEduController.getReleaseHelpEduList(Integer.valueOf(searchMap.get("pageIndex")),Integer.valueOf(searchMap.get("pageSize")),null,null,parameterMap);
                stringObjectMap = JsonUtil.toMap(releaseHelpEduList);
                mapList = JSONArray.parseObject(stringObjectMap.get("data").toString(),List.class);
            }
        }
        return mapList;
    }

    /**
     * 根据赛选条件 返回可变标题
     * @param searchMap 赛选条件
     * @return 可变标题
     */
    private List<String> getHead(Map<String,String> searchMap) {
        // 赛选条件信息（可能做表头）
        String qitaKey = searchMap.get("qitaKey");
        String zmKey = searchMap.get("zmKey");
        String zdbjKey = searchMap.get("zdbjKey");
        String oldKey = searchMap.get("oldKey");
        String state = searchMap.get("state");
        String stateXj = searchMap.get("stateXj");
        //标题
        List<String> heads = new ArrayList<>(16);
        heads.add("姓名");
        heads.add("性别");
        heads.add("身份证");
        heads.add("户籍地");
        heads.add("原判刑期起日");
        heads.add("原判刑期止日");
        heads.add("现刑期");
        heads.add("状态");
        //核失败
        if(state != null) {
            if(Constants.NumberStr.NUM_STR_FOUR.equals(state)) {
                heads.add("司法所单位");
                heads.add("备注信息");
            }
        }
        //衔接成功
        if(stateXj != null) {
            if(Constants.NumberStr.NUM_STR_ONE.equals(stateXj)) {
                heads.add("接送单位");
                heads.add("联系方式");
            }
        }
        //是否旧数据
        if(StringUtils.isNotBlank(oldKey)) {
            heads.add("是否旧数据");
        }
        //是否帮教对象
        if(StringUtils.isNotBlank(zdbjKey)) {
            heads.add("是否重点帮教对象");
        }
        //罪名
        if(StringUtils.isNotBlank(zmKey)) {
            heads.add("罪名");
        }
        //其他条件
        if(StringUtils.isNotBlank(qitaKey)) {
            heads.add("其他条件");
        }
        return heads;
    }

    /**
     * excel 展示的数据
     * @param mapList mapList
     * @param searchMap searchMap
     * @return List<List < String>>
     */
    private List<List<String>> getRows(List<Map<String,String>> mapList,Map<String,String> searchMap) {
        String qitaKey = searchMap.get("qitaKey");
        String zmKey = searchMap.get("zmKey");
        String zdbjKey = searchMap.get("zdbjKey");
        String oldKey = searchMap.get("oldKey");
        String state = searchMap.get("state");
        String stateXj = searchMap.get("stateXj");
        List<List<String>> rows = new ArrayList<>(16);
        mapList.forEach(sign -> {
            List<String> objs = new ArrayList<>();
            objs.add(sign.get("pname"));
            objs.add(sign.get("sex"));
            if(null==sign.get("idnumOpen")){
                objs.add(sign.get("idnum"));
            }else{
                objs.add(sign.get("idnumOpen"));
            }
            objs.add(sign.get("nativeName"));
            objs.add(sign.get("rjDate"));
            objs.add(sign.get("cjDate"));
            objs.add(sign.get("xxqzr"));
            objs.add(sign.get("zt"));
            //核失败
            if(state != null) {
                if(Constants.NumberStr.NUM_STR_FOUR.equals(state)) {
                    objs.add(sign.get("createUserName"));
                    objs.add(sign.get("priReason"));
                }
            }
            //衔接成功
            if(stateXj != null) {
                if(Constants.NumberStr.NUM_STR_ONE.equals(stateXj)) {
                    objs.add(sign.get("usernameXj"));
                    objs.add(sign.get("liaPhone"));
                }
            }
            //是否旧数据
            if(StringUtils.isNotBlank(oldKey)) {
                if(Constants.NumberStr.NUM_STR_ONE.equals(oldKey)) {
                    objs.add("是");
                } else {
                    objs.add("否");
                }
            }
            //是否帮教对象
            if(StringUtils.isNotBlank(zdbjKey)) {
                if(Constants.NumberStr.NUM_STR_ZERO_ONE.equals(zdbjKey)) {
                    objs.add("是");
                } else {
                    objs.add("否");
                }
            }
            //罪名
            if(StringUtils.isNotBlank(zmKey)) {
                List<String> ids = Arrays.asList(zmKey.split(","));
                List<String> nameList = searchCodeList.getCodeNames(ids);
                StringBuilder stringBuilder = new StringBuilder();
                nameList.forEach(s -> stringBuilder.append(s).append(" "));
                objs.add(stringBuilder.toString());
            }
            //其他条件
            if(StringUtils.isNotBlank(qitaKey)) {
                String[] qitaKeys = qitaKey.split(",");
                StringBuilder qita = new StringBuilder();
                for(String str : qitaKeys) {
                    switch(str) {
                        case Constants.NumberStr.NUM_STR_ONE:
                            qita.append("三无人员");
                            break;
                        case Constants.NumberStr.NUM_STR_TWO:
                            qita.append("三假人员");
                            break;
                        case Constants.NumberStr.NUM_STR_THREE:
                            qita.append("危安犯人员");
                            break;
                        case Constants.NumberStr.NUM_STR_FOUR:
                            qita.append("再犯罪倾向");
                            break;
                        case Constants.NumberStr.NUM_STR_FIVE:
                            qita.append("涉黑，涉恶人员");
                            break;
                        case Constants.NumberStr.NUM_STR_SIX:
                            qita.append("双列管人员");
                            break;
                        case Constants.NumberStr.NUM_STR_SEVEN:
                            qita.append("有未成年子女");
                            break;
                        case Constants.NumberStr.NUM_STR_EIGHT:
                            qita.append("走访");
                            break;
                        default:
                            break;
                    }
                }
                objs.add(qita.toString());
            }
            rows.add(objs);
        });
        return rows;
    }

    /**
     * 导出动态excel表格
     * @param request request
     * @param map map封装了redis搜索条件
     * @param excelName excel名
     * @param response response
     * @param type 是否勾选批量导出状态
     */
    public void exportExcelFileTwo(HttpServletRequest request,Map<String,Object> map,String excelName,HttpServletResponse response,String type) throws IOException {
        //搜索条件，取最近的一次的key，获取搜索条件
        Map<String,String> searchMap = getSearchMap(map);
        //数据信息
        List<Map<String,String>> mapList = getData(map,searchMap,type);
        //excel 获取可变表头
        List<String> heads = getHead(searchMap);
        //excel 获取可变数据
        List<List<String>> rows = getRows(mapList,searchMap);
        //工作簿
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.LEFT);
        //工作页
        SXSSFSheet eachSheet = workbook.createSheet();
        // 标题
        SXSSFRow head = eachSheet.createRow(Constants.Number.NUM_ZERO);
        for(int i = 0; i < heads.size(); i++) {
            CellStyle newstyle = workbook.createCellStyle();
            //行头
            Font headFont = workbook.createFont();
            headFont.setBold(true);
            headFont.setFontName("宋体");
            headFont.setFontHeightInPoints((short)11);
            newstyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
            if(Constants.Number.NUM_EIGHT < i) {
                newstyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            }
            head.createCell(i).setCellValue(heads.get(i));
            eachSheet.setColumnWidth(i,100 * 40);
        }
        eachSheet.setColumnWidth(3,100 * 80);
        int acount = Constants.Number.NUM_ZERO;
        //数据
        for(int i = 1; i <= rows.size(); i++) {
            //行
            SXSSFRow eachRow = eachSheet.createRow(i);
            //列（单元格）
            for(int j = 0; j < heads.size(); j++) {
                eachRow.createCell(j).setCellValue(rows.get(acount).get(j));
            }
            acount++;
        }
        // 开始导入
        PoiUtil.downLoadExcelToWebsite(workbook,response,excelName);
    }
}